<template>
  <section class="component data-box">
    <div class="row between-span" v-if="showTopSlot">
      <div>
        <slot name="buttons"></slot>
      </div>
      <div>
        <slot name="append"></slot>
      </div>
    </div>
    <div class="table">
      <el-table :row-class-name="rowClassName" :cell-style="cellStyle" :emptyText="emptyText" :height="tableHeight()" :max-height="maxHeight" tooltip-effect="dark" ref="table" :data="data" border :highlight-current-row="selectionRow!=undefined" @current-change="updateSelectionRow" @select="updateSelectionList" :row-key="getRowKeys" @select-all="updateSelectionList" @sort-change="onSortChange" :span-method="spanMethod" :stripe="stripe">
        <el-table-column v-if="selectionList" type="selection" :reserve-selection="reserveSelection" width="40">
        </el-table-column>
        <el-table-column v-if="!hiddenIndex" type="index" :label="indexLabel" width="50">
        </el-table-column>
        <slot name="columns"></slot>
      </el-table>
    </div>
    <div class="row between-span">
      <div class="databox-title">
        <slot name="footer"></slot>
      </div>
      <el-pagination v-if="showPage&&page&&data&&data.length>0" size="small" :layout="page.layout" :total="page.total" :current-page.sync="page.pageIndex" :page-size.sync="page.pageSize" :page-sizes="page.pageSizeOpts" @size-change="pageSizeChange" @current-change="pageIndexChange"></el-pagination>
    </div>
  </section>
</template>

<script lang="ts">
import Vue from "vue";
import Component from "vue-class-component";
import { Watch, Prop, Emit } from "vue-property-decorator";
import { PageService } from "~/utils/page.service";
import { SortService } from "~/utils/sort.service";
import { Table } from "element-ui";
import { CaseMarkColor } from "~/config/enum.config";

@Component({
  components: {}
})
export default class DataBox extends Vue {
  public table: any;
  // 数据列表
  @Prop() private data: any[];
  // 分页数据
  @Prop() private page: PageService;
  // 隐藏分页
  @Prop({ default: true })
  private showPage: any;
  //是否分页记忆选中
  @Prop({ default: false })
  private reserveSelection: any;
  // 分页数据
  @Prop() private sort: SortService;
  // 选择列表
  @Prop() private selectionList: any;
  // 选择项
  @Prop() private selectionRow: any;
  @Prop({ default: 528 })
  private maxHeight: number;
  @Prop() private height: any;

  @Prop({ type: Boolean })
  private hiddenIndex;

  //用来判断是否合并单元格
  @Prop({ type: Boolean })
  private isSpan;

  @Prop({
    type: String,
    default: "序号"
  })
  private indexLabel;
  // 列样式
  @Prop({
    type: Function,
    default: () => ""
  })
  private rowClassName;
  // 斑马线
  @Prop({
    default: true
  })
  private stripe: boolean;

  // 合并行对应的键
  @Prop({
    type: String
  })
  private rowSpanKey;

  /**
   * 是否展示caseMark
   */
  @Prop({ type: Boolean, default: false })
  private showCaseMark: boolean;
  /**
   * TODO节点流转设置模块 数据返显勾选checkbox标识
   */
  @Prop({ type: Boolean, default: false })
  private nodeFlowModify: boolean;
  /**
   *  清除选择项
   */
  public clearSelection() {
    this.table.clearSelection();
    this.table.setCurrentRow();
  }

  // 分页信息改变消息
  @Emit("onPageChange")
  private pageConfigChange(page) { }
  // 更新选择项列表
  @Emit("update:selectionList")
  private updateSelectionList(list) { }
  // 更新当前选择项
  @Emit("update:selectionRow")
  private updateSelectionRow(row) { }

  // 监听当前选中行变化
  @Watch("selectionRow", { immediate: true })
  private onSelectionRowChange(val: string, oldVal: string) {
    this.$nextTick(() => {
      this.table.setCurrentRow(val);
    });
  }

  // 监听当前选中列表变化
  @Watch("selectionList", { immediate: true })
  private onSelectionListChanged(val: any[], oldVal: any[]) {
    if (!val) {
      return;
    }
    //  等待data 渲染完毕之后再进行选中行赋值
    this.$nextTick(() => {
      // 待删除检测
      // val.forEach((row) => {
      //   const target = this.table.store.states.selection.find((x) => x === row);
      //   if (!target) {
      //     this.table.toggleRowSelection(row, true);
      //   }
      // });

      // // 待删除检测
      // this.table.store.states.selection.forEach((row) => {
      //   const target = this.table.store.states.selection.find((x) => x === row);
      //   if (!target) {
      //     this.table.toggleRowSelection(row, false);
      //   }
      // });

      //TODO 判断是否有节点流转使用标识（不影响其他模块使用databox组件）
      if(this.nodeFlowModify){
        this.data.forEach(row => {
          const checkFlag = this.selectionList.some(x=>{
            if(x.conditionType===row.conditionType){
              return true 
            }
            return false
          })
          this.table.toggleRowSelection(row, checkFlag);
        })
        return
      }
      this.data.forEach(row => {
        const checkFlag = this.selectionList.includes(row)
        // console.log(checkFlag,"监听selectionList")
        this.table.toggleRowSelection(row, checkFlag);
      })
      

    });
  }
  private getRowKeys(row){
    // console.log(row.id,"row.id")
    return row.id
  }
  private tableHeight() {
    if (this.height === "") {
      return this.maxHeight;
    } else {
      return this.height;
    }
  }

  private get showTopSlot() {
    return this.$slots.buttons || this.$slots.append
  }

  private get emptyText() {
    return this.data ? "暂无数据" : " ";
  }
  /**
   * 组件初始化
   */
  private mounted() {
    this.table = this.$refs["table"] as any;
  }

  /**
   * 监听绑定数据变化
   */
  @Watch("data")
  private onDataChanged(newVal: string, oldVal: string) { 
    if(!this.data.length && this.page){
      if(this.page.totalPage < this.page.pageIndex){
        this.page.pageIndex = this.page.totalPage
        setTimeout(() => {
          this.pageConfigChange(this.page);
        }, 500);
      }
    }
    //监听响应数据回显显示选中状态
    // this.data.forEach(row => {
    //   // console.log(this.selectionList,'selectionList')
    //   const checkFlag = this.selectionList.some(x=>{
    //     if(x.caseNumber===row.caseNumber){
    //       return true 
    //     }
    //     return false
    //   })
    //   // console.log(checkFlag,row,"监听data变化")

    //   this.table.toggleRowSelection(row, checkFlag);
    //   //  console.log(checkFlag,row,"监听data变化1")
    // })
  }

  /**
   * 页码数量变化回调
   */
  private pageSizeChange(value) {
    this.page.pageIndex = 1;
    this.page.pageSize = value;
    this.pageConfigChange(this.page);
  }

  /**
   * 页码位置变化回调
   */
  private pageIndexChange(value) {
    this.page.pageIndex = value;
    this.pageConfigChange(this.page);
  }

  /**
   * 排序改变
   */
  private onSortChange({ column, prop, order }) {
    if (this.sort) {
      this.sort.update(prop, order);
      this.pageConfigChange(this.page);
    }
  }

  /**
   * 获取当前行颜色
   * 设置全行的样式
   */
  private cellStyle({ row, rowIndex }: any) {
    if (!this.showCaseMark) return null;
    const style: any = {};
    const marker: any = CaseMarkColor.find(v => v.value === row.caseMark);
    if (marker) {
      style.backgroundColor = marker.color;
    }
    return style;
  }

  private spanMethod({ row, column, rowIndex, columnIndex }) {
    if (!this.rowSpanKey) return
    const columnProperty = this.rowSpanKey
    if (column.property !== columnProperty) return
    // 当前单元格的值
    const currentValue = row[columnProperty]
    const span = {
      rowspan: 0,
      colspan: 0
    }
    const beforRow = rowIndex > 0 ? this.data[rowIndex - 1] : null
    if (beforRow && beforRow[columnProperty] === currentValue) return span

    // 如果当前单元格的值与上一行的对应单元格的值一致，则合并行已经计算过
    span.colspan = 1
    span.rowspan = 1
    let nextRowIndex = rowIndex + 1
    while (nextRowIndex < this.data.length) {
      // 如果下一行对应单元格的值与当前单元格的值一致
      const nextRowValue = this.data[nextRowIndex][columnProperty]
      if (nextRowValue === currentValue) span.rowspan += 1
      nextRowIndex += 1
    }
    return span
  }
}
</script>

<style lang="less" scoped>
.component.data-box {
  padding: 10px;
  & > * {
    margin-bottom: 10px;
  }
}
</style>
<style lang="less">
.data-box.component {
  @line-height: 26px;
  .el-input-number {
    line-height: @line-height;
    width: inherit;
    &__decrease,
    &__increase {
      height: calc(@line-height - 2px);

      width: 35px;
    }
    &__increase {
      right: 5px;
    }
    &__decrease {
      left: 5px;
    }
  }
}
</style>
